/**
 * 公用函数库
 * @return {[type]} [description]
 */
;(function(g){

  if(!g.wxqf_common) return false;

  var common = g.wxqf_common;

  /**
   * 属性区
   */

  // 跳转地址暂存
  common._redirectPages = [];

  /**
   * 获取appName
   * @return {String}
   */
  common.getAppName = function()
  {
    var manifest = chrome.runtime.getManifest();
    return manifest.name +'V' + manifest.version;
  };

  /**
   * 获取appid
   * @return {String}
   */
  common.getAppKey = function()
  {
    return "9e81d3fc63742e4a8556d414053c5697";
  };

  /**
   * 获取urlToken
   * @param  {Function} cb [description]
   * @return {[type]}      [description]
   */
  common.getUrlToken = function(cb)
  {
    var me = this;
    chrome.tabs.query({ url: "https://mp.weixin.qq.com/cgi-bin/*", windowType: "normal" }, function(tabs){
      if ( !tabs.length ) {
        cb('');
        return;
      }
      for( var i =0; i<tabs.length; i++) {
        var urlArr = me.parseUrl(tabs[i].url);
        if ( urlArr.queryParams.token ) {
          cb(urlArr.queryParams.token);
          return;
        }
      }
      return cb('');
    });
  };

  /**
   * 通知tab下墙消息
   * @param  {Object} data
   * @return {[type]}      [description]
   */
  common.sendToTab = function(data)
  {
    chrome.tabs.query({ }, function(tabs){
      if ( tabs.length ) {
        for (var i =0; i<tabs.length; i++) {
          if (tabs[i].url && tabs[i].url.indexOf('mp.weixin.qq.com') > -1) {
            chrome.tabs.sendMessage(tabs[i].id, data);
          }
        }
      }
    });
  };

  /**
   * 显示popup图标上的label文字
   */
  common.setBadgeText = function(text)
  {
    chrome.browserAction.setBadgeText({
      'text':text
    });
    chrome.browserAction.setBadgeBackgroundColor({
      'color': '#51a351'
    });
  };

  /**
   * 将某个tab页设置为当前tab
   */
  common.activeTab = function(tab, config, cb)
  {
    chrome.tabs.update(tab.id, config, cb);
  };

  /**
   * 创建一个tab
   */
  common.createTab = function(config, cb)
  {
    chrome.tabs.create(config, cb);
  };


  /**
   * 获取登录的url
   */
  common.gotoLoginPageUrl = function()
  {
    var url = this.getPageUrl('login');

    chrome.tabs.query({ url: "https://mp.weixin.qq.com/*", windowType: "normal" }, function(tabs){
      if ( tabs.length ) {
        for( var i =0; i<tabs.length; i++) chrome.tabs.remove(tabs[i].id);
      }
      window.open(url);
    });
  };

  /**
   * 获取群发界面的url
   */
  common.gotoMassSendPageUrl = function(token)
  {
    var url = this.getPageUrl('massSend', token);
    var me  = this;
    chrome.tabs.query({ url: "https://mp.weixin.qq.com/*"}, function(tabs){
      if ( tabs.length ) {
        var tmpTab = tabs[0];
        for( var i =1; i<tabs.length; i++) {
          chrome.tabs.remove(tabs[i].id);
        }
        me.activeTab(tmpTab, { active:true, highlighted:true, url: url });
        return;
      }
      window.open(url);
    });
  };

  /**
   * 设置要跳转的页面地址
   * @param {String} pageName 页面名称
   * @param {Boolean} isClear 是否重置
   */
  common.setRedirectPage = function(pageName, isClear)
  {
    if (isClear) {
      this._redirectPages = [pageName];
      return;
    }

    this._redirectPages.push(pageName);
  };



  /////////////////////////////////////////////
  // api函数列表
  //  1.必带3个参数（msg, sender, cb）
  //  2. 返回格式为object，有两个预置字段
  //    a. result 返回结果
  //    b. error 返回错误信息
  /////////////////////////////////////////////

  /**
   * 获取绑定的公众账号
   * @return {String}
   */
  common.getBindWeixinName = function(msg, sender, cb)
  {
    var weixinName = "Nodejs小站";
    if (cb) cb({'result':true, data:weixinName});
    return weixinName;
  };

  /**
   * content scripts 显示通知
   * @description api
   */
  common.showNoti = function(msg, sender, cb)
  {
    mpNotification.noti(msg.id, msg.title, msg.content, msg.cover);
    if(cb) cb({'result': true});
  };

  /**
   * 关闭桌面通知
   * @description api
   */
  common.closeNoti = function(msg, sender, cb)
  {
    mpNotification.close(msg.id);
    if (cb) cb({'result': true});
  };

  /**
   * 获取到要跳转的页面
   * @description api
   */
  common.getRedirectPage = function(msg, sender, cb)
  {
    if (this._redirectPages.length) {
      cb({'result': this._redirectPages.pop()});
    } else {
      cb({'result': ''});
    }
  };

  /**
   * 添加消息发送任务
   */
  common.messageAddTask = function(msg, sender, cb)
  {
    // if ($.md5(msg.weixin_name + chrome.runtime.id) != this.getAppKey()) {
    //   cb({'result': false, 'error':"您当前登录的公众号不是助手绑定的微信账号[1]"});
    //   return;
    // }
    cb(wxqf_task.add(msg, sender));
  };

  /**
   * 获取消息详情
   */
  common.messageGetDetail = function(msg, sender, cb)
  {
    cb(wxqf_task.getDetail(msg, sender));
  };

  /**
   * 获取一个
   */
  common.messageGetOne = function(msg, sender, cb)
  {
    cb(wxqf_task.getOne(msg, sender));
  };

  /**
   * 完成一个
   */
  common.messageCompleteOne = function(msg, sender, cb)
  {
    cb(wxqf_task.completeOne(msg, sender));
  };

  /**
   * 添加用户
   */
  common.messageAddUser = function(msg, sender, cb)
  {
    cb(wxqf_task.addUser(msg, sender));
  };

  /**
   * 设置任务进度
   */
  common.messageSetProgress = function(msg, sender, cb)
  {
    var ret = wxqf_task.setProgress(msg.progress, sender);
    cb({'result': true});
  };

  /**
   * 获取系统配置
   */
  common.getSysConfig = function(msg, sender, cb)
  {
    var conf = wxqf_task.getSysConfig();
    cb({'result': true, 'config':conf});
  };

})(window);
























/**
 * 消息任务
 */
;(function(g){

  if(g.wxqf_task) return ;

  var task = g.wxqf_task = {};

  // 状态说明
  task.progressMap = {
    0 : '未建立',
    1 : '已建立',
    //4 : '开始获取用户',
    5 : '正在获取用户',
    10: '获取用户完毕',
    11: '开始发送',
    15: '发送完毕'
  };

  var _config = {
    // 每页抓取用户数量
    'pageNum': 10,
    // 每页抓取时间间隔
    'timePerPage': 5,
    // 抓取、发送失败重试次数
    'retryNum': 2,
    // 发送时间间隔
    'sendTime': 3,
    // 每次同时发送的用户数量
    'sendCount': 1,
    // 发送超时时间
    'sendWaitTime': 180,
    // 默认cache时间：3小时（单位：分钟）
    'userCacheTime': 180,
    // 是否初始化过
    'inited': false
  };

  /**
   * 获取系统配置
   */
  task.getSysConfig = function()
  {
    if (!_config.inited) {
      var manifest = chrome.runtime.getManifest();
      var conf = localStorage.getItem('wxqfzs_sys_config-'+ manifest.version);
      if (conf) {
        conf = JSON.parse(conf);
        task.setSysConfig(conf);
      }
      _config.inited = true;
    }

    _config.appKey = wxqf_common.getAppKey();
    return _config;
  };

  /**
   *  设置系统配置
   */
  task.setSysConfig = function(config)
  {
    _config.pageNum        = parseInt(config.pageNum)        || _config.pageNum;
    _config.timePerPage    = parseInt(config.timePerPage)    || _config.timePerPage;
    _config.retryNum       = parseInt(config.retryNum)       || _config.retryNum;
    _config.sendTime       = parseInt(config.sendTime)       || _config.sendTime;
    _config.sendCount      = parseInt(config.sendCount)      || _config.sendCount;
    _config.sendWaitTime   = parseInt(config.sendWaitTime)   || _config.sendWaitTime;
    _config.userCacheTime  = !isNaN(config.userCacheTime) ? parseInt(config.userCacheTime)  : _config.userCacheTime;

    // 将配置存在本地
    var manifest = chrome.runtime.getManifest();
    localStorage.setItem('wxqfzs_sys_config-'+ manifest.version, JSON.stringify(_config));
    return _config;
  };

  /**
   * 初始化任务
   */
  task.init = function(data)
  {
    if (!data) data = {};
    // 当前进度
    this._windonwId = 0;
    this._tabid     = 0;
    this._progress = data._progress || 0;
    // 要发送的组id
    this._groupid  = data._groupid || null;
    // 要发送的消息内容
    this._message  = data._message || null;
    // 展示用的消息内容
    this._messageHtml = data._messageHtml || '';
    // 要发送的用户列表
    this._userList = data._userList || [];
    // 已发送的用户
    this._sentUserList = data._sentUserList || [];
    // 失败的用户
    this._failedUserList = data._failedUserList || [];
    // 正在执行的
    this._runningUserList = data._runningUserList || [];
    // 执行次数记录
    this._runningTimes = data._runningTimes || {};
    // 开始执行的时间
    this._startTimes =  data._startTimes || {};
    // 消息自带要发送的用户
    this._messageUserList = data._messageUserList || null;


    // 清除定时器
    clearInterval(this._checkTimer);
    var me = this;
    this._checkTimer = setInterval(function(){
      // 检查超时
      me.checkRunning();
      // 序列化
      //me.serialize();
    }, 20*1000);
  };

  /**
   * 返回当前任务状态
   * @return {int}
   */
  task.getProgress = function()
  {
    if ('undefined' == typeof this._progress) {
      this.init();
    }
    return this._progress;
  };

  /**
   * 设置当前状态
   * @param {Int} progressId 进度id
   * @return {Boolean}
   */
  task.setProgress = function(progressId, sender)
  {
    if (progressId == 5 && sender && this.getProgress() ==1) {
      this._tabid     = sender.tab.id;
      this._windonwId = sender.tab.windowId;
    }
    progressId = parseInt(progressId);
    if (!progressId) {
      return false;
    }
    if (!this.progressMap[progressId]) {
      return false;
    }

    this._progress = progressId;
    return true;
  };

  /**
   * 添加任务
   * @param {Object} data
   * @return {Object}
   */
  task.add = function(data, sender)
  {
    // 未发送或已发送完毕
    //if (!this.getProgress() || this.getProgress() == 15) {
      this.init();
    //}
    if (this.getProgress() != 0) {
      return {'result': false, 'error': '当前还有待发送的消息，你需要取消后才能发送'};
    }

    this._groupid     = data.groupid;
    this._message     = data.message;
    this._messageHtml = data.messageHtml;
    this._messageUserList = data.userList || null;
    this.setProgress(1);

    return {'result': true};
  };

  /**
   * 添加用户
   */
  task.addUser = function(data, sender)
  {
    if (!this._tabid) {
      this._tabid = sender.tab.id;
      this._windonwId = sender.tab.windowId;
    }
    if (sender.tab.id != this._tabid) {
      //return {'result': false, 'error':'当前的页面窗口不是最初打开的窗口', error_no:10001};
    }
    // 已经
    if (this.getProgress() != 5) {
      return {'result': false, 'error':'当前未处于获取用户状态环节'};
    };
    this._userList = data.userList;
    this.setProgress(10);

    return {'result': true};
  };

  /**
   * 获取一个用户task
   */
  task.getOne = function(data, sender)
  {
    if (!this._tabid) {
      this._tabid = sender.tab.id;
      this._windonwId = sender.tab.windowId;
    }
    if (sender.tab.id != this._tabid) {
      //return {'result': false, 'error':'当前的页面窗口不是最初打开的窗口', error_no:10001, detail: (this.getDetail()).data};
    }

    if (this.getProgress() < 10) {
      return {'result':false, 'error': '对不起，用户未获取完毕，不能执行发送任务', detail: (this.getDetail()).data};
    }

    if (this._userList.length == 0) {
      // 判断是否完成
      if (this._runningUserList.length == 0) {
        this.setProgress(15);
      }
      return {'result': '已全部发送完毕', detail: (this.getDetail()).data};
    }

    var user = this._userList.shift();

    if (this.getProgress() == 10) {
      this.setProgress(11);
    }

    // 设置开始时间
    this._startTimes[user.id] = (new Date).getTime();
    if (!this._runningTimes[user.id]) {
      this._runningTimes[user.id] = 1;
    } else {
      this._runningTimes[user.id]++;
    }

    this._runningUserList.push(user);

    if(wxqf_common.DEBUG) console.log('taskgetOne: ', user, this._runningTimes, this._startTimes);

    return {'result':true, 'user':user, detail: (this.getDetail()).data};
  };

  /**
   * 添加一个已完成的用户
   */
  task.completeOne = function(data, sender)
  {

    if(wxqf_common.DEBUG) console.log('taskcompleteOne: ', data);

    if (!this._tabid) {
      this._tabid = sender.tab.id;
      this._windonwId = sender.tab.windowId;
    }
    if (sender.tab.id != this._tabid) {
      //return {'result': false, 'error':'当前的页面窗口不是最初打开的窗口', error_no:10001};
    }

    if (this.getProgress() < 11) {
      return {'result':false, 'error': '消息发送进度不匹配'};
    }

    var user = data.user, idx = -1;
    var id = parseInt(user.id);
    for (var i = 0; i < this._runningUserList.length; i++) {
      if(id == this._runningUserList[i].id) {
        idx = i;
        break;
      }
    }

    if (idx == -1) {
      return {'result':false, 'error': '未在正在执行的队列里找到此用户'};
    }

    // 从runnninglist 删除
    this._runningUserList.splice(idx, 1);

    // 重复执行两次
    if (!data.result && this._runningTimes[id] && this._runningTimes[id] < _config.retryNum) {
      // 添加到未完成的用户列表
      this._userList.unshift(data.user);
    } else if(!data.result) {
      this._failedUserList.push(data.user);
    } else {
      this._sentUserList.push(data.user);
    }

    // 判断是否完成
    if (this._userList.length == 0 && this._runningUserList.length == 0) {
      this.setProgress(15);
    }

    if(wxqf_common.DEBUG) console.log('taskcompleteOne2: ', data, this._runningUserList);
    return {'result': true};
  };

  /**
   * 检查正在执行的任务是否超时
   * @return {[type]} [description]
   */
  task.checkRunning = function()
  {
    if(!this._runningUserList.length) return false;

    var me = this;

    for (var i = 0; i < this._runningUserList.length; i++) {

      if(!this._runningUserList[i].id) continue;

      (function(user){

        setTimeout(function(){
          // 3分钟为超时时间
          var nowT = (new Date).getTime();
          var maxT = _config.sendWaitTime*1000;
          var startT = me._startTimes[user.id];
          if (!startT || (nowT - startT > maxT)) {
            var data = { result: false, user: user, error: 'timeout' };
            var sender = { tab: { id: me._tabid, windowId: me._windonwId } };
            if (wxqf_common.DEBUG) console.log("checkRunning: data, sender", data, sender);
            me.completeOne(data, sender);
          }
        }, 1);

      })(this._runningUserList[i]);

    }
  };

  /**
   * 重置工作窗口
   */
  task.resetWorkTab = function()
  {
    this._tabid = 0;
    this._windonwId = 0;
  };

  /**
   * 获取详情
   */
  task.getDetail = function(data, sender)
  {
    return {
      'result': true,
      data:{
        tabid: this._tabid,
        windowId: this._windonwId,
        groupid: this._groupid,
        message: this._message,
        messageHtml: this._messageHtml,
        messageUserList: this._messageUserList,
        leftNum: this._userList.length,
        sentNum: this._sentUserList.length,
        failedNum: this._failedUserList.length,
        runningNum: this._runningUserList.length,
        progress: this.getProgress(),
        config: this.getSysConfig()
      }
    };
  };

  /**
   * 任务序列化暂存
   */
  task.serialize = function()
  {
    var S = {};

    try {
      // var data = JSON.stringify(this);
      var data = this;
    } catch(e) {
      if (wxqf_common.DEBUG) console.log('task.serialize failed: ', e);
      return false;
    }

    S.data    = data;
    S.addTime = (new Date).getTime();

    try {

      var obj = {};
      //obj[_getSerializeKey()] = JSON.stringify(S);
      obj[_getSerializeKey()] = S;
      chrome.storage.local.set(obj);

      if (wxqf_common.DEBUG) console.log('task.serialize-> ok');

    } catch(e) {
      if (wxqf_common.DEBUG) console.log('task.serialize-> chrome.storage.local.set failed', e);
      return false;
    }
  };

  /**
   * 任务反序列化
   */
  task.unSerialize = function()
  {
    var key = _getSerializeKey(), me = this;
    chrome.storage.local.get(key, function(obj){
      var S = obj[key];
      if(!S) {
        if(wxqf_common.DEBUG) console.log('task.unSerialize failed: chrome.storage.local.get return null');
        return;
      }

      /*try {
        S = JSON.parse(S);
      } catch(e) {
        if(wxqf_common.DEBUG) console.log('task.unSerialize failed: JSON.parse S failed', e);
        return;
      }*/

      var now = (new Date).getTime();
      // 过期时间超过24小时则丢弃
      if (now - S.addTime > 24*3600*1000) {
        if(wxqf_common.DEBUG) console.log('task.unSerialize failed: addTime over 24 hours', e);
        return;
      }

      /*try {
        var data = JSON.parse(S.data);
      } catch(e) {
        if(wxqf_common.DEBUG) console.log('task.unSerialize failed: JSON.parse S.data failed', e);
        return;
      }*/

      var data = S.data;

      // 恢复数据
      me.init(data);
    });
  };


  /**
   * 获取序列化的key
   * @return {[type]} [description]
   */
  function _getSerializeKey()
  {
    var manifest = chrome.runtime.getManifest();
    return 'wxqfzs_task_data-' + manifest.version +'-'+ wxqf_common.getAppKey();
  }

})(window);



























/**
 * notify
 */
;(function(g){

  if (g.wxqf_mpNotification) return false;

  var mpNoti = g.wxqf_mpNotification = { };

  /**
   * 属性名
   * @type {Object}
   */
  mpNoti._cache = {};


  /**
   * 创建基本的桌面通知（文本）
   */
  mpNoti.noti = function(id, title, content, cover)
  {
    id    = id || 'wxqfzs_noti';
    title = title || '微信群发助手';
    cover = cover || '/images/icon-48.png';

    var noti = webkitNotifications.createNotification(cover, title, content);
    noti.replaceId = id;
    noti.show();

    this._cache[id] = noti;
    return noti;
  };

  /**
   * 创建带html的桌面通知
   */
  mpNoti.notiHtml = function(id, file)
  {
    if ( !id ) id = 'wxqfzs_noti';
    var noti = webkitNotifications.createHTMLNotification(
        file
      );
    noti.replaceId = id;
    noti.show();

    this._cache[id] = noti;
    return noti;
  };

  /**
   * 隐藏提示信息
   */
  mpNoti.close = function(id){
    if (!id) id = 'wxqfzs_noti';
    if ( this._cache[id] ) {
      if(typeof this._cache[id].cancel == 'function') {
        this._cache[id].cancel();
      } else if (typeof this._cache[id].close == 'function') {
        this._cache[id].close();
      }
    }
  };

})(window);